import 'dart:convert';

import 'package:event_bus/event_bus.dart';
import 'package:flutter/services.dart';
import 'package:flutter_city_picker/listener/picker_listener.dart';
import 'package:flutter_city_picker/model/city.dart';

class CityPickerResult {
  String? provinceCode;
  String? provinceName;
  String? cityCode;
  String? cityName;
  String? districtCode;
  String? districtName;
  CityPickerResult({
    this.provinceCode,
    this.provinceName,
    this.cityCode,
    this.cityName,
    this.districtCode,
    this.districtName,
  });

  Map toJson() => {
    "provinceCode": provinceCode,
    "provinceName": provinceName,
    "cityCode": cityCode,
    "cityName": cityName,
    "districtCode": districtCode,
    "districtName": districtName,
  };

  @override
  String toString(){
    return toJson().toString();
  }
}

class CityPickerDriver extends EventBus implements CityPickerListener {
  Map<String, List<City>>? cityData;
  final result = CityPickerResult();

  @override
  Future<List<City>> loadProvinceData() async {
    if (cityData == null) {
      Map<String, dynamic> data =
          await rootBundle.loadStructuredData<Map<String, dynamic>>(
              "assets/json/areas.json", (value) async => jsonDecode(value));
      cityData = data.map((key, value) => MapEntry(
          key,
          (value as Map)
              .entries
              .map<City>((item) => City(name: item.value, code: item.key))
              .toList()));
    }
    return cityData?["0"] ?? <City>[];
  }

  @override
  Future<List<City>> onProvinceSelected(
      String? provinceCode, String? provinceName) async {
    result.provinceCode = provinceCode;
    result.provinceName = provinceName;
    return cityData?["0,${result.provinceCode}"] ?? <City>[City(code:"${result.provinceCode}00",name:result.provinceName)];
  }

  @override
  Future<List<City>> onCitySelected(String? cityCode, String? cityName) async {

    result.cityCode = cityCode;
    result.cityName = cityName;
    return cityData?["0,${result.provinceCode},${result.cityCode}"] ?? <City>[City(code:"${result.cityCode}00",name:result.cityName)];
  }

  @override
  void onFinish(String? provinceCode, String? provinceName, String? cityCode,
      String? cityName, String? districtCode, String? districtName) {
    fire(CityPickerResult(
      provinceCode: provinceCode,
      provinceName: provinceName,
      cityCode: cityCode,
      cityName: cityName,
      districtCode: districtCode,
      districtName: districtName,
    ));
  }
}
